package cn.enilu.guns.admin.modular.door;

import cn.enilu.guns.admin.common.constant.device.AuthorizeConstant;
import cn.enilu.guns.admin.common.constant.device.ParamConstant;
import cn.enilu.guns.admin.common.constant.device.TableConstant;
import cn.enilu.guns.admin.core.base.tips.AuthorizeErrorTip;
import cn.enilu.guns.admin.core.base.tips.SetDataToDeviceTip;
import cn.enilu.guns.admin.core.util.EntranceDataUtil;
import cn.enilu.guns.admin.equipment.dto.UserauthorizeDto;
import cn.enilu.guns.admin.equipment.transform.GetDeviceDataTransform;
import cn.enilu.guns.bean.dto.UserDto;
import cn.enilu.guns.bean.entity.door.*;
import cn.enilu.guns.admin.equipment.service.EntranceGuardService;
import cn.enilu.guns.business.DoorBusiness;
import cn.enilu.guns.service.door.DoorInfoService;
import cn.enilu.guns.service.door.EntranceGardUserService;
import cn.enilu.guns.service.door.EquipmentInfoService;

import cn.enilu.guns.bean.annotion.core.BussinessLog;
import cn.enilu.guns.bean.constant.factory.PageFactory;
import cn.enilu.guns.bean.dictmap.CommonDict;
import cn.enilu.guns.admin.core.base.controller.BaseController;

import cn.enilu.guns.bean.vo.query.Page;
import cn.enilu.guns.bean.vo.query.SearchFilter;


import cn.enilu.guns.service.door.EventRecordService;
import cn.enilu.guns.service.system.impl.ConstantFactory;
import cn.enilu.guns.utils.BeanUtil;
import cn.enilu.guns.utils.IpUtils;
import cn.enilu.guns.utils.Lists;
import cn.enilu.guns.utils.license.CheckAuthorizeCode;
import cn.enilu.guns.warpper.door.EquipmentInfoWarpper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/door/EQUIPMENT/INFO")
public class EquipmentInfoController extends BaseController {
	private  Logger logger = LoggerFactory.getLogger(getClass());
	@Autowired
	private EquipmentInfoService equipmentInfoService;
	@Autowired
	private EntranceGuardService entranceGuardService;
	@Autowired
	private DoorInfoService doorInfoService;
    @Autowired
    private DoorBusiness doorBusiness;
	@Autowired
	private EventRecordService eventRecordService;
	@Autowired
	private EntranceGardUserService entranceGardUserService;

	private static String PREFIX = "/door/EQUIPMENT/INFO/";

	/**
	* 跳转到首页
	*/
	@RequestMapping(value="",method = RequestMethod.GET)
		public String index() {
		return PREFIX + "index.html";
	}

	/**
	* 跳转到添加页面
	*/
	@RequestMapping(value = "/add",method = RequestMethod.GET)
		public String add(Model model) {
		try {
			Long count = equipmentInfoService.count();
			if (!CheckAuthorizeCode.AuthorizeCode(AuthorizeConstant.LICENSE_PATH,AuthorizeConstant.XM_NAME, AuthorizeConstant.XZQH,count)) {
				model.addAttribute("message","系统未授权，请联系客服获取授权码");
			}else{
				model.addAttribute("message","");

			}
		} catch (Exception e) {
			model.addAttribute("message",e.getMessage());
			e.printStackTrace();
		}
		return PREFIX + "add.html";
	}


	/**
	 * 跳转到添加页面
	 */
	@RequestMapping(value = "/addOnSearch",method = RequestMethod.GET)
	public String addOnSearch(EquipmentInfo equipmentInfo,Model model) {
		try {
			Long count = equipmentInfoService.count();
			if (!CheckAuthorizeCode.AuthorizeCode(AuthorizeConstant.LICENSE_PATH,AuthorizeConstant.XM_NAME, AuthorizeConstant.XZQH,count)) {
				model.addAttribute("message","系统未授权，请联系客服获取授权码");
			}else{
				model.addAttribute("message","");
			}

			String rs = entranceGuardService.getControllerTypeAndSerialNumber(equipmentInfo.getIpAddress());
			Map<String,String> map = EntranceDataUtil.parseParams(rs);
			equipmentInfo.setControllerType(map.get(ParamConstant.LOCK_COUNT));
			equipmentInfo.setSerialNumber(map.get(ParamConstant.SERIAL_NUMBER));
			equipmentInfo.setCommunicationPost("4370");
			equipmentInfo.setEquipmentName(equipmentInfo.getIpAddress());
			equipmentInfo.setCommunicationMode("1");
			model.addAttribute("item",equipmentInfo);

		} catch (Exception e) {
			model.addAttribute("message",e.getMessage());
			equipmentInfo = new EquipmentInfo();
			e.printStackTrace();
		}
		if(!equipmentInfoService.checkIpExist(equipmentInfo)){
			equipmentInfo = new EquipmentInfo();
			model.addAttribute("message","该设备IP已添加");
		}
		model.addAttribute("item",equipmentInfo);
		return PREFIX + "addOnSearch.html";
	}

	/**
	* 跳转到修改页面
	*/
	@RequestMapping("/edit/{id}")
	public String edit(@PathVariable Long id, Model model) {
		EquipmentInfo entity = equipmentInfoService.get(id);
        model.addAttribute("controllerName", ConstantFactory.me().getControllerName(Integer.valueOf(entity.getControllerType())));
		model.addAttribute("item",entity);
		return PREFIX + "edit.html";
	}
	@RequestMapping(value = "/list",method = RequestMethod.POST)
	@ResponseBody
	public Object list(@RequestParam(required = false) String equipmentName) {
		Page<EquipmentInfo> page = new PageFactory<EquipmentInfo>().defaultPage();
		page.addFilter("equipmentName", SearchFilter.Operator.EQ,equipmentName);
		page = equipmentInfoService.queryPage(page);
        Page<Object> pageEquipmentInfoWarpper =  new PageFactory<Object>().defaultPage();
        BeanUtils.copyProperties(page,pageEquipmentInfoWarpper);
        pageEquipmentInfoWarpper.setRecords((List<Object>) new EquipmentInfoWarpper(BeanUtil.objectsToMaps(page.getRecords())).warp());
		return super.packForBT(pageEquipmentInfoWarpper);
	}
	/**
	* 新增设备信息表
	*/
	@RequestMapping(value = "/add",method = RequestMethod.POST)
	@ResponseBody
	@BussinessLog(value = "新增设备信息表", key = "name",dict= CommonDict.class)
	public Object add(EquipmentInfo equipmentInfo) {
		try {
			//获取门禁设备总数
			Long count = equipmentInfoService.count();
			if (!CheckAuthorizeCode.AuthorizeCode(AuthorizeConstant.LICENSE_PATH,AuthorizeConstant.XM_NAME, AuthorizeConstant.XZQH,count)) {
				return  new AuthorizeErrorTip("系统未授权，请联系客服获取授权码");
			}
		} catch (Exception e) {
			return  new AuthorizeErrorTip(e.getMessage());
		}
		//检查IP是否正确
        if(!IpUtils.isRightIP(equipmentInfo.getIpAddress())){
        	return IPERROR_TIP;
		}

		if(!entranceGuardService.checkDeviceOnline(equipmentInfo.getIpAddress())){
			SetDataToDeviceTip setDataToDeviceTip = new SetDataToDeviceTip(201,"设备数量读取错误,设备不在线");
			return setDataToDeviceTip;
		}

		if(!equipmentInfoService.checkIpExist(equipmentInfo)){
			SetDataToDeviceTip setDataToDeviceTip = new SetDataToDeviceTip(201,"该设备IP已添加");
			return setDataToDeviceTip;
		}
		String rs = entranceGuardService.getControllerTypeAndSerialNumber(equipmentInfo.getIpAddress());
        if("0".equals(rs)){
        	return LOCK_COUNT_ERROR_TIP;
		}
		Map<String,String> map = EntranceDataUtil.parseParams(rs);
		equipmentInfo.setControllerType(map.get(ParamConstant.LOCK_COUNT));
		equipmentInfo.setSerialNumber(map.get(ParamConstant.SERIAL_NUMBER));
//		equipmentInfo.setControllerType("2");
//		equipmentInfo.setSerialNumber("123123123123");
		equipmentInfoService.insert(equipmentInfo);
		//根据门禁控制器类型生成门信息
		int doorNum = Integer.valueOf(equipmentInfo.getControllerType());
		for(int i = 1; i <= doorNum ;i++){
			DoorInfo doorInfo = new DoorInfo();
			doorInfo.setDoorName(equipmentInfo.getId() + "-" + i);
			doorInfo.setAreaId(equipmentInfo.getAreaId());
			doorInfo.setEquipmentInfo(equipmentInfo);
			doorInfo.setDoorNo(i+"");
			doorInfoService.insert(doorInfo);

		}
		return SUCCESS_TIP;
	}

	/**
	* 删除设备信息表
	*/
	@RequestMapping(value = "/delete")
	@ResponseBody
	@BussinessLog(value = "删除设备信息表", key = "id",dict= CommonDict.class)
	public Object delete(@RequestParam Long id) {
		//刪除相应的门信息
		doorInfoService.deleteDoorInfoByEquipmentInfoId(id);
		equipmentInfoService.delete(id);
		return SUCCESS_TIP;
	}

	/**
	* 修改设备信息表
	*/
	@RequestMapping(value = "/update")
	@ResponseBody
	@BussinessLog(value = "修改设备信息表", key = "name",dict= CommonDict.class)
	public Object update(EquipmentInfo equipmentInfo) {
		//检查IP是否正确
		if(!IpUtils.isRightIP(equipmentInfo.getIpAddress())){
			return IPERROR_TIP;
		}
		equipmentInfoService.update(equipmentInfo);

		return SUCCESS_TIP;
	}

	/**
	 * 同步所有数据到设备
	 */
	@RequestMapping(value = "/setDataToDevice")
	@ResponseBody
	@BussinessLog(value = "同步所有数据到设备", key = "id",dict= CommonDict.class)
	public Object setDataToDevice(@RequestParam Long id) {
		//清除该设备所有人员数据
		EquipmentInfo equipmentInfo = equipmentInfoService.get(id);
		entranceGuardService.cleanDeviceData(equipmentInfo.getIpAddress(),TableConstant.TABLE_USER);
		//清除权限
		entranceGuardService.cleanDeviceData(equipmentInfo.getIpAddress(),TableConstant.USERAUTHORIZE);
		//清除时段
		entranceGuardService.cleanDeviceData(equipmentInfo.getIpAddress(),TableConstant.TABLE_TIMEZONE);
        //获取所有门信息
        String strTip = "";
        List<SearchFilter> searchFilters = Lists.newArrayList();
        searchFilters.add(new SearchFilter("equipmentInfo.id",SearchFilter.Operator.EQ,id));
        List<DoorInfo> doorInfos = doorInfoService.queryAll(searchFilters);
        try {
			for (DoorInfo doorInfo : doorInfos) {
				List<EntranceGuardRule> entranceGuardRules = doorBusiness.getEntranceGuardRules(doorInfo.getId());
				for (EntranceGuardRule entranceGuardRule : entranceGuardRules) {
					//向设备中写入人员信息
					List<UserCard> userCards = entranceGardUserService.getUserAndCardInfoByRuleId(entranceGuardRule.getId());
					entranceGuardService.addDataToDoor(doorInfo, TableConstant.TABLE_USER, userCards);

					//向设备中写入时段
					//todo 根据权限获取时段信息,设置时段信息
					entranceGuardService.addDataToDoor(doorInfo, TableConstant.TABLE_TIMEZONE, entranceGuardRule.getTimeInfo().toString());

					//向设备中写入权限信息
					List<UserauthorizeDto> userauthorizeDtos = Lists.newArrayList();
					for (UserCard userCard : userCards) {
						UserauthorizeDto userauthorizeDto = new UserauthorizeDto();
						userauthorizeDto.setUserId(userCard.getUserInfo().getId());
						//todo 添加时段信息
						userauthorizeDto.setTimeInfoId(entranceGuardRule.getTimeInfo().getId());
						userauthorizeDto.setDoorId(Long.valueOf(doorInfo.getDoorNo()));
						userauthorizeDtos.add(userauthorizeDto);
					}
					entranceGuardService.addDataToDoor(doorInfo, TableConstant.USERAUTHORIZE, userauthorizeDtos);
				}
			}
		}catch (Exception e){
        	logger.error("同步数据失败："+e.getMessage());
			SetDataToDeviceTip setDataToDeviceTip = new SetDataToDeviceTip(202,"同步失败");
			return setDataToDeviceTip;
		}
        SetDataToDeviceTip setDataToDeviceTip = new SetDataToDeviceTip(200,"同步成功");
        return setDataToDeviceTip;
	}

	/**
	 * 获取事件记录
	 */
	@RequestMapping(value = "/getRecord")
	@ResponseBody
	@BussinessLog(value = "获取事件记录", key = "id",dict= CommonDict.class)
	public Object getRecord(@RequestParam Long id) {
        EquipmentInfo equipmentInfo = equipmentInfoService.get(id);
        String rs = entranceGuardService.getTransactionToDevice(equipmentInfo.getIpAddress());
        if("0".equals(rs)){
            SetDataToDeviceTip setDataToDeviceTip = new SetDataToDeviceTip(202,"设备连接失败");
            return setDataToDeviceTip;
        }
		///todo 存储设备时间记录
		String[] records = rs.split("\r\n");
		for (int i = 1; i < records.length; i++) {
			EventRecord eventRecord = GetDeviceDataTransform.transformToEventRecord(records[i]);
			eventRecord.setEquipmentId(id);
			eventRecord.setAreaName(ConstantFactory.me().getAreaName(equipmentInfo.getAreaId().intValue()));
			eventRecord.setVerifiedName(ConstantFactory.me().getVerifiedName(eventRecord.getVerified()));
			eventRecord.setInoutState(ConstantFactory.me().getInoutStateName(Integer.valueOf(eventRecord.getInoutState())));
//			System.out.println(eventRecord);
			eventRecordService.insert(eventRecord);
		}
        return SUCCESS_TIP;
	}

	/**
	 * 同步设备时间
	 */
	@RequestMapping(value = "/setDateTime")
	@ResponseBody
	@BussinessLog(value = "同步设备时间", key = "id",dict= CommonDict.class)
	public Object setDateTime(@RequestParam Long id) {
        EquipmentInfo equipmentInfo = equipmentInfoService.get(id);
        String rs = entranceGuardService.setTimeToDevice(equipmentInfo.getIpAddress());
        SetDataToDeviceTip setDataToDeviceTip = new SetDataToDeviceTip(202,rs);
        return setDataToDeviceTip;
	}

	/**
	 * 获取人员信息
	 */
	@RequestMapping("/openUserForDevice/{id}")
	public String openUserForDevice(@PathVariable Long id, Model model) {
		EquipmentInfo entity = equipmentInfoService.get(id);
		model.addAttribute("controllerName", ConstantFactory.me().getControllerName(Integer.valueOf(entity.getControllerType())));
		model.addAttribute("item",entity);
		return PREFIX + "edit.html";
	}
}